/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.common.service;

import java.lang.reflect.Type;
import java.lang.reflect.ParameterizedType;
import java.text.NumberFormat;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.thinkgem.jeesite.common.persistence.CrudDao;
import com.thinkgem.jeesite.common.persistence.DataEntity;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.modules.sys.dao.ColumnDao;
import com.thinkgem.jeesite.modules.sys.dao.IdentifierDao;
import com.thinkgem.jeesite.modules.sys.entity.Column;
import com.thinkgem.jeesite.modules.sys.entity.Identifier;
import com.thinkgem.jeesite.modules.sys.entity.IdentifierType;
import com.thinkgem.jeesite.modules.sys.entity.Role;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;

/**
 * Service基类
 * @author ThinkGem
 * @version 2014-05-16
 */
@Transactional(readOnly = true)
public abstract class CrudService<D extends CrudDao<T>, T extends DataEntity<T>> extends BaseService {
	
	
	
	/** 实体类类型 */
	private Class<T> entityClass;
	
	/**
	 * 
	 * 构造函数
	 * 
	 * 通过反射获取泛型的第二个参数 (坐标0开始)
	 */
	@SuppressWarnings("unchecked")
	public CrudService(){
		Type type = getClass().getGenericSuperclass();
		Type[] parameterizedType = ((ParameterizedType) type).getActualTypeArguments();
		entityClass = (Class<T>) parameterizedType[1];
	}
	
	/**
	 * 标识符 DAO
	 * 
	 */
	@Autowired
	protected IdentifierDao identifierDao;
	
	/**
	 * 
	 * 列管理 DAO
	 * 
	 */
	@Autowired
	protected ColumnDao columnDao ;
	
	/**
	 * 持久层对象
	 */
	@Autowired
	protected D dao;
	
	/**
	 * 获取单条数据
	 * @param id
	 * @return
	 */
	public T get(String id) {
		return dao.get(id);
	}
	
	/**
	 * 获取单条数据
	 * @param entity
	 * @return
	 */
	public T get(T entity) {
		return dao.get(entity);
	}
	
	/**
	 * 查询列表数据
	 * @param entity
	 * @return
	 */
	public List<T> findList(T entity) {
		return dao.findList(entity);
	}
	
	/**
	 * 查询分页数据
	 * @param page 分页对象
	 * @param entity
	 * @return
	 */
	public Page<T> findPage(Page<T> page, T entity) {
		entity.setPage(page);
		page.setList(dao.findList(entity));
		return page;
	}

	/**
	 * 保存数据（插入或更新）
	 * @param entity
	 */
	@Transactional(readOnly = false)
	public void save(T entity) {
		
		String className = entity.getClass().getSimpleName();
		logger.debug("className  = " + className);
		Identifier identifier = identifierDao.findIdentifierCode(className);
		logger.debug("----identifier---" + identifier);
		if (  identifier == null ) {
			if (entity.getIsNewRecord()){
				entity.preInsert();
				dao.insert(entity);
			}else{
				entity.preUpdate();
				dao.update(entity);
			}
		}else{
			if (entity.getIsNewRecord()){
				entity.preInsert();
				String  identifierFlag  = identifier.getIdentifierType().getIdentifierFlag();
				//查找此条编号的长度
				int nfLength = identifier.getLength();
				logger.debug("长度为 : "  +nfLength);
				if ( identifierFlag.equals( IdentifierType.IDENTIFIER_FLAG_SERIAL ) ) { //流水号
					logger.debug("流水号");
					NumberFormat nf = NumberFormat.getInstance();
					nf.setGroupingUsed(false);	//设置最大整数位数
					nf.setMaximumIntegerDigits(nfLength);//设置最小整数位数   
					nf.setMinimumIntegerDigits(nfLength);//获取当前表,最后一条数据
					T lastCodeEntity = dao.findLastCode();
					logger.debug("------- last Code"  +lastCodeEntity);
					//判断当前表,最后一条数据codeNum是否有值  如果没有,就默认为1
					if ( lastCodeEntity == null || lastCodeEntity.getCodeNum() == null || lastCodeEntity.getCodeNum().equals("") ) {
						entity.setCodeFlag( 1 );
						entity.setCodeNum( nf.format(1) );
					} else {
						int lastCodeFlag = lastCodeEntity.getCodeFlag();
						int currentCodeFlag = lastCodeFlag + 1 ;
						logger.debug( "最后一个编号 =" + lastCodeFlag + " , 当前编号 =" + currentCodeFlag );
						if ( (currentCodeFlag + "").length() >= nfLength ) {
							entity.setCodeNum( currentCodeFlag + "" );
						} else {
							entity.setCodeNum( nf.format( currentCodeFlag ) );
						}
						entity.setCodeFlag( currentCodeFlag );
					}
					dao.insert(entity);
				} else if ( identifierFlag.equals( IdentifierType.IDENTIFIER_FLAG_DEFINED ) ) {
					logger.debug("自定义");
					String rule	= identifier.getRule();
					entity.setCodeNum(rule);
					dao.insert(entity);
				} else {
					logger.debug("当前标识符标志不存在 =" + identifierFlag );
				}
			}else{
				entity.preUpdate();
				dao.update(entity);
			}
		}
	}
	
	/**
	 * 删除数据
	 * @param entity
	 */
	@Transactional(readOnly = false)
	public void delete(T entity) {
		dao.delete(entity);
	}
	
	/**
	 * 查询最后一条编号
	 * @param entity
	 * 
	 */
	@Transactional(readOnly = false)
	public T findLastCodeNum(){
		return dao.findLastCode();
	}
	
	/**
	 * 根据当前实体类
	 * 
	 * 获取所有需要显示的列
	 * 
	 */
	public List<Column> findColumnList(){
		logger.debug("当前的实体类 =" + entityClass.getSimpleName() );
		Column column = new Column();
		//根据当前实体类,获取实体类对应的列数据
		column.setClassName(entityClass.getSimpleName());
		column = columnDao.findByClassName( column );
		User user = UserUtils.getUser();
		//这里需要重新修改,因为一个用户会对应多个角色
		List<Role> roleList = user.getRoleList();
		if ( roleList.size() == 0 ) {
			logger.debug("当前用户没有角色配置 !");
			return null ;
		} else {
			//根据实体类的列数据,获取归属于实体类的所有属性
			Column parent = new Column();
			parent.setId( column.getId() );
			column.setParent( parent );
			column.setRoleId( roleList.get(0).getId() );
			logger.debug("当前用户信息 =" + user.getName() + " , role =" + column.getRoleId() + " , parentID =" + parent.getId() );
			List<Column> columns = columnDao.findListByParendId( column );
			return columns ;
		}
		
	}
	
}
